using UnityEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using HotFix.Script;
using UnityEngine.UI;
using HybridCLR;

#pragma warning disable CS0618
public class GameManager : MonoBehaviour
{
    public static GameManager Instance;

    public Canvas canvas;

    private void Awake()
    {
        Instance = this;
    }


    System.IO.MemoryStream fs;

    System.IO.MemoryStream p;

    // ??????????

    public Action<float> OnUpdate;

    public delegate void shopUpda(); //

    public shopUpda MethodField; //


    private void Start()
    {
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
        Application.targetFrameRate = -1;
        if (GameConfig.IsUpdate)
        {
           
            Utils.IsUpdate = GameConfig.IsUpdate;
            GameObject prefab = Resources.Load<GameObject>("LoadView");
            GameObject obj = GameObject.Instantiate<GameObject>(prefab, canvas.transform);
            DownLoadManager.Instance.onDownLoad = (fileName,msg,progress) =>
            {
                obj.transform.Find("Progress/di/progress").GetComponent<Image>().fillAmount = progress;
                string uu = progress.ToString("F2");
                obj.transform.Find("txt_proress").GetComponent<Text>().text = float.Parse(uu) * 100 + "%";
                
                // obj.transform.Find("Slider").GetComponent<Slider>().value = progress;
                // string uu = progress.ToString("F2");
                // obj.transform.Find("txt_proress").GetComponent<Text>().text = float.Parse(uu) * 100 + "%";
            };
            StartCoroutine(DownLoadManager.Instance.Start(gameObject, () =>
            {
                string localVerPath = GameConfig.DataPath + "version.txt";
                GameObject.Destroy(obj);
                OnResourceInited();

            },()=> {
                //obj.transform.Find("StrongUpdate").GetComponent<Button>().onClick.AddListener(() =>
                //{
                //    Application.OpenURL("");
                //});
                Debug.LogError("==============需要强更新================下载Zip============");

            }, (float progress) =>
            {
                obj.transform.Find("Slider").GetComponent<Slider>().value = progress;
                string uu = progress.ToString("F2");
                obj.transform.Find("txt_proress").GetComponent<Text>().text = float.Parse(uu) * 100 + "%";
                
            }));
        }
        else
        {
            OnResourceInited();
        }
    }


    public void OnApplicationPause(bool pauseStatus)
    {
        Utils.OnApplicationPauseCallBack?.Invoke(pauseStatus);
        
    }
    Assembly hotUpdateAss;
        
    void OnResourceInited()
    {
        Utils.Reflect += Reflect;
        Utils.DownLoadGameFiles = DownLoadManager.Instance.DownLoadGameFiles;
        Utils.OnDownLoadGameFiles = (Action<string,string, float> action) =>
        {
            DownLoadManager.Instance.onDownLoad = null;
            DownLoadManager.Instance.onDownLoad = action;
        };
        Utils.MainBehaviour = this;

        
#if !UNITY_EDITOR||false
                List<string> aotMetaAssemblyFiles = new List<string>() { "mscorlib.dll.bytes", "System.dll.bytes", "System.Core.dll.bytes" };
                foreach (var aotDllName in aotMetaAssemblyFiles)
                {
                    byte[] dllBytes = File.ReadAllBytes(GameConfig.DataPath+aotDllName);
                    // 加载assembly对应的dll，会自动为它hook。一旦aot泛型函数的native函数不存在，用解释器版本代码
                    LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, HomologousImageMode.SuperSet);
                    Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{HomologousImageMode.SuperSet} ret:{err}");
                }
                hotUpdateAss = Assembly.Load(File.ReadAllBytes($"{GameConfig.DataPath}/HotFix.dll.bytes"));
                Utils.Reflect("HotFix.Script.StartUp").GetType().GetMethod("Start", BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
                //Type entryType = hotUpdateAss.GetType("StartUp");
                //entryType.GetMethod("Start", BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
#else
        hotUpdateAss = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotFix");
        StartUp.Start();
#endif

    }





    public object Reflect(string className)
    {
        Debug.Log(className);

        Type t = hotUpdateAss.GetType(className);
        object obj = t.Assembly.CreateInstance(className);
        return obj;
    }

    private void OnDestroy()
    {
        if (fs != null)
            fs.Close();
        if (p != null)
            p.Close();
        fs = null;
        p = null;
    }


    public void Update()
    {
        Utils.OnUpdate?.Invoke(0);
        // DownLoadManager.Instance.Update();
    }

    private void FixedUpdate()
    {
        Utils.OnFixUpdate?.Invoke();
       
    }
}